package com.hjh.testdemo.ui.usb.host

import android.R.attr.text
import android.app.PendingIntent
import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import android.content.IntentFilter
import android.hardware.usb.UsbDevice
import android.hardware.usb.UsbDeviceConnection
import android.hardware.usb.UsbManager
import android.text.Spannable
import android.text.SpannableStringBuilder
import android.text.style.ForegroundColorSpan
import android.view.Menu
import android.view.MenuInflater
import android.view.MenuItem
import androidx.core.content.ContextCompat
import androidx.core.view.MenuProvider
import androidx.fragment.app.viewModels
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.lifecycleScope
import androidx.navigation.fragment.findNavController
import com.elvishew.xlog.XLog
import com.hjh.core.activity.BaseFragment
import com.hjh.testdemo.BuildConfig
import com.hjh.testdemo.R
import com.hjh.testdemo.databinding.FragmentUsbHostBinding
import com.hjq.toast.Toaster
import com.hoho.android.usbserial.driver.UsbSerialDriver
import com.hoho.android.usbserial.driver.UsbSerialPort
import com.hoho.android.usbserial.util.SerialInputOutputManager
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch


/**
 * @author： hjh
 * @createDate： 2025/6/16 19:39
 * @description：
 * @qq： 3472903821
 * @version: 1.0
 */
class UsbHostFragment : BaseFragment<FragmentUsbHostBinding>(),
    SerialInputOutputManager.Listener {

    private enum class UsbPermission {
        Unknown, Requested, Granted, Denied
    }

    companion object {
        private const val WRITE_WAIT_MILLIS = 2_000
        private const val READ_WAIT_MILLIS = 2_000
        private const val INTENT_ACTION_GRANT_USB = BuildConfig.APPLICATION_ID + ".GRANT_USB";
    }

    private val deviceId = 0
    private val portNum: Int = 0
    private val baudRate: Int = 0
    private val withIoManager = false
    private val usbIoManager: SerialInputOutputManager? = null
    private var usbSerialPort: UsbSerialPort? = null
    private val usbPermission: UsbPermission = UsbPermission.Unknown
    private val connected = false

    private lateinit var usbManager: UsbManager
    private var driver: UsbSerialDriver? = null
    private var device: UsbDevice? = null
    private var connection: UsbDeviceConnection? = null

    private val viewModel: UsbHostViewModel by viewModels({ requireParentFragment() })

    override fun initView() {
        ContextCompat.registerReceiver(
            requireActivity(),
            usbReceiver,
            IntentFilter(INTENT_ACTION_GRANT_USB),
            ContextCompat.RECEIVER_NOT_EXPORTED
        )
    }

    override fun initListener() {
        binding.sendBtn.setOnClickListener {
            onButtonClick()
        }
    }

    override fun initToolbar() {
        menuProvider = object : MenuProvider {
            override fun onCreateMenu(menu: Menu, menuInflater: MenuInflater) {
                menuInflater.inflate(com.hjh.testdemo.R.menu.menu_terminal, menu)
            }

            override fun onMenuItemSelected(menuItem: MenuItem): Boolean {
                val id: Int = menuItem.itemId
                if (id == R.id.clear) {
                    binding.receiveText.text = ""
                } else if (id == R.id.send_break) {
                    if (!connected) {
                        Toaster.show("未连接")
                    } else {
                        try {
                            usbSerialPort?.setBreak(true)
                            Thread.sleep(100) // should show progress bar instead of blocking UI thread
                            usbSerialPort?.setBreak(false)
                            val spn = SpannableStringBuilder()
                            spn.append("send <break>\n")
                            spn.setSpan(
                                ForegroundColorSpan(
                                    ContextCompat.getColor(
                                        requireContext(),
                                        com.hjh.res.R.color.colorSendText
                                    )
                                ),
                                0,
                                spn.length,
                                Spannable.SPAN_EXCLUSIVE_EXCLUSIVE
                            )
                            binding.receiveText.append(spn)
                        } catch (_: UnsupportedOperationException) {
                            Toaster.show("不支持该操作")
                        } catch (e: Exception) {
                            Toaster.show(
                                "BREAK 失败: " + e.message,
                            )
                        }
                    }
                }
                return true
            }
        }
        menuHost.addMenuProvider(
            menuProvider as MenuProvider,
            viewLifecycleOwner,
            Lifecycle.State.RESUMED
        )
    }

    override fun onDestroyView() {
        requireActivity().unregisterReceiver(usbReceiver)
        disconnectDevice()
        super.onDestroyView()
    }

    private fun checkUsbDevices() {
        val deviceList = usbManager.deviceList
        for (usbDevice in deviceList.values) {
            if (usbDevice.vendorId == 0x2D95 && usbDevice.productId == 0x6011) {
                device = usbDevice
                requestUsbPermission()
                return
            }
        }
        logMessage("未发现目标USB设备")
    }

    private fun requestUsbPermission() {
        val permissionIntent = PendingIntent.getBroadcast(
            requireContext(), 0, Intent(INTENT_ACTION_GRANT_USB), PendingIntent.FLAG_IMMUTABLE
        )
        device?.let {
            usbManager.requestPermission(it, permissionIntent)
        }
    }

    @Suppress("Deprecation")
    private val usbReceiver = object : BroadcastReceiver() {
        override fun onReceive(context: Context?, intent: Intent?) {
            when (intent?.action) {
                INTENT_ACTION_GRANT_USB -> {
                    synchronized(this) {
                        if (intent.getBooleanExtra(UsbManager.EXTRA_PERMISSION_GRANTED, false)) {
                            logMessage("已获取USB权限，尝试连接设备")
                            connect()
                        } else {
                            logMessage("USB权限被拒绝")
                        }
                    }
                }

                UsbManager.ACTION_USB_DEVICE_DETACHED -> {
                    val detachedDevice: UsbDevice? =
                        intent.getParcelableExtra(UsbManager.EXTRA_DEVICE)
                    if (detachedDevice != null && detachedDevice == device) {
                        logMessage("USB设备已断开")
                        disconnectDevice()
                    }
                }
            }
        }
    }

    private fun connect() {
        usbManager = requireContext().getSystemService(Context.USB_SERVICE) as UsbManager
        for (v in usbManager.getDeviceList().values) if (v.deviceId == deviceId) device = v
        if (device == null) {
            // status("connection failed: device not found")
            return
        }
        driver = viewModel.usbSerialDriver.value
        if (driver == null) {
            Toaster.show("无效设备")
            findNavController().navigateUp()
            return
        }
        connection = usbManager.openDevice(driver?.device)
        if (connection == null) {
            return
        }
        usbSerialPort = driver?.ports?.first()
        usbSerialPort?.open(connection)
        usbSerialPort?.setParameters(115200, 8, UsbSerialPort.STOPBITS_1, UsbSerialPort.PARITY_NONE)

    }

    private fun startRead() {
    }

    private fun sendResponse(message: String) {
        // if (connection != null && endpointOut != null) {
        //     val data = message.toByteArray()
        //     val bytesWritten = connection!!.bulkTransfer(endpointOut, data, data.size, 1000)
        //     if (bytesWritten > 0) {
        //         logMessage("已发送响应: $message")
        //     } else {
        //         logMessage("发送响应失败")
        //     }
        // }
    }

    private fun disconnectDevice() {
        usbSerialPort?.close()
        usbSerialPort = null
    }

    private fun logMessage(message: String) {
        XLog.d(message)
        Toaster.show(message)
        lifecycleScope.launch(Dispatchers.Main) {
            binding.receiveText.append(message + "\n")
        }
    }

    fun onButtonClick() {
        val inputString = binding.sendText.text.toString()
        if (inputString.isEmpty()) {
            return
        }

        sendResponse(inputString)
        logMessage(getString(com.hjh.res.R.string.local_send) + inputString)
        binding.sendText.setText("")
    }

    override fun onNewData(data: ByteArray?) {
        TODO("Not yet implemented")
    }

    override fun onRunError(e: Exception?) {
        TODO("Not yet implemented")
    }
}